home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_08_03 / 8n03115a < prev    next >
Text File  |  1990-03-18  |  12KB  |  349 lines

  1. #include "stdlib.h"
  2. #include "stdio.h"
  3. #include "conio.h"
  4. #include "string.h"
  5. #include "graph.fd"
  6. #include "halo.h"
  7.  
  8. #define OK     1
  9. #define FAIL   0
  10. #define TRUE   1
  11. #define FALSE  0
  12.  
  13. #define CMD_DELIMITER " \t\n"
  14. #define VAL_DELIMITER ",\n"
  15. #define TICK_WIDTH    0.025
  16. #define SQRT_2        1.414213562
  17.  
  18. char *cmd_strs[] = {"DATA","COLORS","MODE","ATTRIBUTES","SCALE","LEGEND",
  19.    "FONT","TITLES","DEVICE","PRINTER","COMMENT","END" };
  20. enum cmd_vals { C_DATA, C_COLORS, C_MODE, C_ATTRIBUTES, C_SCALE, C_LEGEND,
  21.    C_FONT, C_TITLES, C_DEVICE, C_PRINTER, C_COMMENT, C_END };
  22.  
  23. #define NUM_CMD_VALS   ((int)C_END)
  24. union udata {
  25.    float fdata[64];      /* Numeric data for commands (e.g. COLORS) */
  26.    char cdata[16][16];   /* String data for commands (e.g. LEGEND)  */
  27.    };
  28.  
  29. typedef struct cmd_data_type {
  30.    union udata d;          /* Commands data is string or numeric    */
  31.    int count;              /* Number of data items found in command */
  32.    } cmd_data_type, *cmd_data_type_p;
  33.  
  34. typedef struct {           /* HALO '88 specific global data         */
  35.    char *device;           /* Name of HALO screen device driver     */
  36.    char *font;             /* Name of HALO stroke font file         */
  37.    float x1,y1,x2,y2;      /* World coordinates rectangle values    */
  38.    int degree_mode;        /* if true use degrees, else radians     */
  39.    int lnstyle;            /* Line style, 1 <= lnstyle <= 10        */
  40.    int lnwidth;            /* Line thickness in pixels, always odd  */
  41.    int maxcolor;           /* Number of colors supported by device  */
  42.    int mode;               /* Device dependent graphics mode        */
  43.    } halo_type;
  44.  
  45. typedef struct {
  46.    float start_x, start_y;     /* Bottom corner of graph draw area  */
  47.    float end_x, end_y;         /* Upper corner of graph draw area   */
  48.    float scale_min, scale_max; /* Y-Axis min and max values         */
  49.    int num_points;             /* Number of points in DATA file     */
  50.    int num_ticks;              /* Number of ticks on the Y-Axis     */
  51.    int num_colors;             /* Number of user-supplied colors    */
  52.    char *legend;               /* User-supplied LEGEND              */
  53.    } graph_type;
  54.  
  55. cmd_data_type cmd_data[NUM_CMD_VALS];
  56. halo_type halo;
  57. graph_type graph;
  58.  
  59. main(argc,argv)
  60. int argc;
  61. char **argv;
  62. {
  63.    char inp_line[128];
  64.    FILE *infile;
  65.  
  66.    if (argc>1) {  /* First argv should be input data file */
  67.       if ((infile=fopen(argv[1],"r")) == NULL) {
  68.          fprintf(stderr,"Error:  can't open %s\n",argv[1]);
  69.          exit(-1);
  70.          }
  71.       }
  72.    else {         /* no data file was given              */
  73.       fprintf(stderr,"Usage:  graph inputfile\n");
  74.       exit(-1);
  75.       }
  76.  
  77.    memset(cmd_data, 0, sizeof(cmd_data));
  78.  
  79.    while(fgets(inp_line,sizeof(inp_line)-1,infile) != NULL)
  80.       process_graphics_cmd_line(inp_line);
  81.    fclose(infile);
  82.  
  83.    setup_halo_globals();     /* Capture relevant parameters    */
  84.    setup_graph_globals();
  85.    draw_bar_graph();         /* Draw the actual graph          */
  86.    deltcur();                /* Remove text "_" cursor         */
  87.    getch();
  88.    print_graph();            /* Print graph if requested       */
  89.    closegraphics();          /* Close out all devices          */
  90.    return OK;
  91. }
  92.  
  93.  
  94.  
  95. int process_graphics_cmd_line(inp_line)
  96. char *inp_line;
  97. {
  98.    char input[128];
  99.    char *cmd_keywd;
  100.    int found = FALSE;
  101.    int cmd_val;
  102.  
  103.    strcpy(input,inp_line);
  104.    if ((cmd_keywd=strtok(input,CMD_DELIMITER)) == NULL) {
  105.       fprintf(stderr,"Unable to parse to command <%s>\n",inp_line);
  106.       return FAIL;
  107.       }
  108.  
  109.    for (cmd_val=0; cmd_val<=NUM_CMD_VALS; cmd_val++)
  110.       if (stricmp(cmd_strs[cmd_val],cmd_keywd)==0) {
  111.          found = TRUE;
  112.          break;
  113.          }
  114.  
  115.    if (!found) {
  116.       fprintf(stderr,"Keyword <%s> not recognized.\n",cmd_keywd);
  117.       return FAIL;
  118.       }
  119.  
  120.    if (cmd_val <= C_SCALE)
  121.       parse_delimited_number_list(&cmd_data[cmd_val]);
  122.    else
  123.       parse_delimited_string_list(&cmd_data[cmd_val]);
  124.    return OK;
  125. }
  126.  
  127.  
  128.  
  129. void parse_delimited_number_list(data_p)
  130. cmd_data_type *data_p;
  131. {
  132.    int i;
  133.    char *cmd_data;
  134.  
  135.    i = data_p->count;
  136.    while ((cmd_data=strtok(NULL,VAL_DELIMITER)) != NULL)
  137.       data_p->d.fdata[i++] = (float) atof(cmd_data);
  138.    data_p->count = i;
  139. }
  140.  
  141.  
  142.  
  143. void parse_delimited_string_list(data_p)
  144. cmd_data_type_p data_p;
  145. {
  146.    int i;
  147.    char *cmd_data;
  148.  
  149.    i = data_p->count;
  150.    while ((cmd_data=strtok(NULL,VAL_DELIMITER)) != NULL)
  151.       strcpy(data_p->d.cdata[i++],cmd_data);
  152.    data_p->count = i;
  153. }
  154.  
  155.  
  156.  
  157. void setup_halo_globals()
  158. {
  159.    if (cmd_data[C_DEVICE].count)        /* Was there a DEVICE command? */
  160.       halo.device = cmd_data[C_DEVICE].d.cdata[0];
  161.    else                                   /* No, use the default       */
  162.       halo.device = "HALOIBMG.DEV";
  163.    printf("using device <%s>, press any key to start:\n",halo.device);
  164.    getch();
  165.    setdev(halo.device);              /* Initialize the graphics device */
  166.  
  167.    halo.mode = (int) cmd_data[C_MODE].d.fdata[0];
  168.    initgraphics(&halo.mode);             /* Clear screen in given mode */
  169.    halo.degree_mode = 1;
  170.    setdegree(&halo.degree_mode);           /* Use degrees, not radians */
  171.    halo.x1 = (float) 0.0;   halo.y1 = (float) 0.0;
  172.    halo.x2 = (float) 1.0;   halo.y2 = (float) 1.0;
  173.    setworld(&halo.x1,&halo.y1,&halo.x2,&halo.y2); /* World rectangle   */
  174.    inqcrange(&halo.maxcolor );                /* Find max color value  */
  175.    halo.lnwidth = 1;
  176.    setlnwidth(&halo.lnwidth) ;                /* Line width is 1 pixel */
  177.    halo.lnstyle = 1;
  178.    setlnstyle(&halo.lnstyle);                 /* Line style is solid   */
  179.    setcolor(&halo.maxcolor);      /* Max screen color is usually white */
  180.  
  181.    if (cmd_data[C_FONT].count)            /* Was there a FONT command? */
  182.       halo.font = cmd_data[C_FONT].d.cdata[0];
  183.    else                                   /* No, use the default       */
  184.       halo.font = "HALO104.FNT";
  185.    setfont(halo.font);                    /* Load font from disk file  */
  186.    setstclr(&halo.maxcolor,&halo.maxcolor) ;  /* Set stroke text color */
  187. }
  188.  
  189.  
  190. void setup_graph_globals()
  191. {
  192.    float *data_ptr;
  193.    int i;
  194.  
  195.    /* This rectangle is the active drawing area of the global window */
  196.    graph.start_x = (float) 0.1;   graph.end_x = (float) 0.9;
  197.    graph.start_y = (float) 0.15;  graph.end_y = (float) 0.88;
  198.    graph.num_ticks = 10;
  199.    graph.num_points = cmd_data[C_DATA].count;
  200.    graph.num_colors = cmd_data[C_COLORS].count;
  201.    graph.legend = cmd_data[C_LEGEND].d.cdata[0];
  202.  
  203.    if (cmd_data[C_SCALE].count) {  /* User supplied SCALE boundaries */
  204.       graph.scale_min = cmd_data[C_SCALE].d.fdata[0];
  205.       graph.scale_max = cmd_data[C_SCALE].d.fdata[1];
  206.       }
  207.    else { /* No SCALE bounds, use min and max data values for SCALE */
  208.       graph.scale_min = (float) 0.0;
  209.       graph.scale_max = (float) 0.0;
  210.       data_ptr = cmd_data[C_DATA].d.fdata;
  211.       for (i=0; i < graph.num_points; i++, data_ptr++) {
  212.          if (graph.scale_min > *data_ptr)
  213.             graph.scale_min = *data_ptr;  /* New minimum data point */
  214.          if (graph.scale_max < *data_ptr)
  215.             graph.scale_max = *data_ptr;  /* New maximum data point */
  216.          }
  217.       }
  218. }
  219.  
  220.  
  221. void draw_axes(bar_width)
  222. double bar_width;
  223. {
  224.    int i;
  225.    float tick_interval;                  /* Distance between Y-Axis ticks */
  226.    float axis_interval;               /* Y-Axis tick value in scale units */
  227.    float height = (float) 0.10;                     /* Stroke text height */
  228.    float angle = (float) 45.0;               /* Stroke text drawing angle */
  229.    float asp = (float) 1.0;                   /* Stroke text aspect ratio */
  230.    int path = 0;                                      /* Stroke text path */
  231.    float text_height;                   /* Inquired height of text string */
  232.    float text_width;                     /* Inquired width of text String */
  233.    float offse;                                  /* Offset for descenders */
  234.    float x_val, y_val;                       /* General-purpose registers */
  235.    char